const html = `<html>
<head>
  <title>hello world</title>
</head>
  <body>
<h1> hello </h1>
  </body>
</html>
`;

let currentToken = null
let currentAttribute = null
let stack = [{ type: "document", children: [] }]

function emit(token) {
  console.log(token)
  if (token.type === "text")
    return
  let top = stack[stack.length - 1]
  if (token.type === "startTag") {
    let element = {
      type: 'element',
      children: [],
      attributes: []
    }
    element.tagName = token.tagName
    for (let p in token) {
      if (p != "type" && p != "tagName")
        element.attributes.push({
          name: p,
          value: token[p]
        })
    }
  }
}

const EOF = Symbol("EOF");
function data(c) {
  if (c === "<") {
    return tagOpen;
  } else if (c === EOF) {
    emit({
      type: "EOF"
    })
    return;
  } else {
    emit({
      type: "text",
      content: c
    })
    return data;
  }
}

function tagOpen(c) {
  if (c === "/") {
    return endTagOpen;
  } else if (c.match(/^[a-zA-z]$/)) {
    currentToken = {
      type: "startTag",
      tagName: ""
    }
    return tagName(c);
  } else {
    return data;
  }
}

function endTagOpen(c) {
  if (c.match(/^[a-zA-Z]$/)) {
    currentToken = {
      type: "endTag",
      tagName: ""
    }
    return tagName(c);
  } else if (c === ">") {
  } else if (c === EOF) {
  } else {
  }
}

function tagName(c) {
  if (c.match(/^[\t\n\f]$/)) {
    return beforeAttributeName;
  } else if (c === "/") {
    return selfClosingStartTag;
  } else if (c.match(/^[a-zA-Z]$/)) {
    currentToken.tagName += c
    return tagName;
  } else if (c === ">") {
    emit(currentToken)
    return data;
  } else {
    return tagName;
  }
}

function beforeAttributeName(c) {
  if (c.match(/^[\t\n\f]$/)) {
    return beforeAttributeName;
  } else if (c === ">" || c === "/" || c === EOF) {
    return afterAttributeName(c);
  } else if (c === "=") {
    return beforeAttributeName;
  } else {
    return currentAttribute = {
      name: "",
      value: ""
    };
    return attributeName(c)
  }
}

function afterAttributeName(c) {
  if (c.match(/^[a-zA-Z]$/)) {

  } else {

  }

}

function attributeName(c) {

}

function selfClosingStartTag(c) {
  if (c === ">") {
    currentToken.isSelfClosing = true
    return data;
  } else if (c === "EOF") {
  } else {
  }
}

function parseHTML(html) {
  let state = data;
  for (let c of html) {
    state = state(c);
  }
  state = state(EOF);
  console.log(html);
}

parseHTML(html);
